package cn.me.alphamq.nameserver.store;

import cn.me.alphamq.nameserver.cache.Container;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 服务实例的管理者
 *
 * @author f
 */
public class ServiceInstanceManager {

    private static final Logger log = LoggerFactory.getLogger(ServiceInstanceManager.class);

    /**
     * 管理服务实例的表，key："ip:端口"；value：服务实例
     */
    private final Map<String, ServiceInstance> serviceInstanceMap = new ConcurrentHashMap<>();

    /**
     * 将服务实例放入表中
     *
     * @param serviceInstance 服务实例
     */
    public void put(ServiceInstance serviceInstance) {
        serviceInstanceMap.put(getKey(serviceInstance.getIp(), serviceInstance.getPort()), serviceInstance);
    }

    /**
     * 根据服务实例的 ip 和 端口 获取 服务实例
     *
     * @param ip   服务实例的 ip 地址
     * @param port 服务实例的 端口号
     * @return 服务实例
     */
    public ServiceInstance get(String ip, Integer port) {
        return serviceInstanceMap.get(getKey(ip, port));
    }

    /**
     * 根据服务实例的 键 获取 服务实例
     *
     * @param key   服务实例的键(ip:port)
     * @return 服务实例
     */
    public ServiceInstance get(String key) {
        return serviceInstanceMap.get(key);
    }

    // 根据服务实例的 ip 和 端口 获取 key
    private String getKey(String ip, Integer port) {
        return ip + ":" + port;
    }

    /**
     * 移除指定的服务实例，并告知其它 nameserver 节点移除该服务实例
     *
     * @param key 从 ctx 的 attr 中获取的用来唯一标识服务实例的字符串
     */
    public ServiceInstance remove(String key) {
        // 将移除服务实例的消息通知给从节点
        Container.getReplicationMsgQueueManager().putRemovedServiceInstance(key);
        ServiceInstance serviceInstance = serviceInstanceMap.remove(key);
        log.info("service instance [{}] has been removed", key);
        return serviceInstance;
    }

    public Map<String, ServiceInstance> getServiceInstanceMap() {
        return serviceInstanceMap;
    }
}
